"""
字典管理工具类
提供字典数据处理和树形结构构建功能
"""

import logging
from typing import List, Dict, Any, Optional
from datetime import datetime

from src.app.database.models import Dictionary

logger = logging.getLogger(__name__)

class DictionaryUtils:
    """字典工具类"""
    
    def dictionary_to_dict(self, dictionary: Dictionary) -> Dict[str, Any]:
        """
        将字典对象转换为字典格式
        
        Args:
            dictionary: SQLAlchemy字典对象
            
        Returns:
            字典数据字典
        """
        return {
            'dict_id': dictionary.dict_id,
            'dict_type': dictionary.dict_type,
            'dict_code': dictionary.dict_code,
            'dict_name': dictionary.dict_name,
            'parent_code': dictionary.parent_code,
            'sort_order': dictionary.sort_order,
            'is_system': dictionary.is_system,
            'description': dictionary.description,
            'create_time': dictionary.create_time.isoformat() if dictionary.create_time else None,
            'update_time': dictionary.update_time.isoformat() if dictionary.update_time else None
        }
    
    def build_tree_structure(self, dictionaries: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        构建字典树形结构
        
        Args:
            dictionaries: 字典列表
            
        Returns:
            树形结构列表
        """
        # 创建字典映射
        dict_map = {}
        root_items = []
        
        # 第一遍：创建所有节点
        for item in dictionaries:
            node = {
                'dict_id': item['dict_id'],
                'dict_type': item['dict_type'],
                'dict_code': item['dict_code'],
                'dict_name': item['dict_name'],
                'parent_code': item['parent_code'],
                'sort_order': item['sort_order'],
                'is_system': item['is_system'],
                'description': item['description'],
                'children': [],
                'level': 0,
                'expanded': True
            }
            dict_map[item['dict_code']] = node
        
        # 第二遍：构建父子关系
        for item in dictionaries:
            code = item['dict_code']
            parent_code = item['parent_code']
            
            if parent_code and parent_code in dict_map:
                # 添加到父节点的children列表
                parent_node = dict_map[parent_code]
                child_node = dict_map[code]
                child_node['level'] = parent_node['level'] + 1
                parent_node['children'].append(child_node)
            else:
                # 根节点
                root_items.append(dict_map[code])
        
        # 排序：先按层级，再按排序号，最后按代码
        def sort_nodes(nodes):
            nodes.sort(key=lambda x: (x['level'], x['sort_order'], x['dict_code']))
            for node in nodes:
                if node['children']:
                    sort_nodes(node['children'])
        
        sort_nodes(root_items)
        
        return root_items
    
    def flatten_tree(self, tree_nodes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        将树形结构扁平化
        
        Args:
            tree_nodes: 树形节点列表
            
        Returns:
            扁平化字典列表
        """
        result = []
        
        def flatten(nodes):
            for node in nodes:
                # 复制节点并移除children
                flat_node = {k: v for k, v in node.items() if k != 'children'}
                result.append(flat_node)
                
                # 递归处理子节点
                if node['children']:
                    flatten(node['children'])
        
        flatten(tree_nodes)
        return result
    
    def get_tree_path(self, tree_nodes: List[Dict[str, Any]], target_code: str) -> List[str]:
        """
        获取节点在树中的路径
        
        Args:
            tree_nodes: 树形节点列表
            target_code: 目标节点代码
            
        Returns:
            路径列表
        """
        path = []
        
        def find_path(nodes, target, current_path):
            for node in nodes:
                current_path.append(node['dict_name'])
                
                if node['dict_code'] == target:
                    path.extend(current_path)
                    return True
                
                if node['children'] and find_path(node['children'], target, current_path):
                    return True
                
                current_path.pop()
            
            return False
        
        find_path(tree_nodes, target_code, [])
        return path
    
    def validate_tree_structure(self, dictionaries: List[Dict[str, Any]]) -> Dict[str, Any]:
        """
        验证树形结构的有效性
        
        Args:
            dictionaries: 字典列表
            
        Returns:
            验证结果
        """
        errors = []
        warnings = []
        
        # 检查循环引用
        codes = {item['dict_code'] for item in dictionaries}
        
        for item in dictionaries:
            parent_code = item['parent_code']
            if parent_code and parent_code not in codes:
                warnings.append(f"字典项'{item['dict_name']}'的父节点'{parent_code}'不存在")
        
        # 检查深度
        max_depth = 10
        tree = self.build_tree_structure(dictionaries)
        
        def check_depth(nodes, depth=1):
            for node in nodes:
                if depth > max_depth:
                    errors.append(f"字典树深度超过{max_depth}层")
                    return
                
                if node['children']:
                    check_depth(node['children'], depth + 1)
        
        check_depth(tree)
        
        return {
            'valid': len(errors) == 0,
            'errors': errors,
            'warnings': warnings
        }
    
    def get_statistics(self, dict_type: str = None) -> Dict[str, Any]:
        """
        获取字典统计信息
        
        Args:
            dict_type: 字典类型（可选）
            
        Returns:
            统计信息字典
        """
        from src.app.modules.dictionary.service import DictionaryService
        
        service = DictionaryService()
        
        try:
            if dict_type:
                dictionaries = service.get_dictionaries_by_type(dict_type)
                types = [dict_type]
            else:
                dictionaries = []
                types = service.get_all_types()
                for type_name in types:
                    dictionaries.extend(service.get_dictionaries_by_type(type_name))
            
            # 统计信息
            total_count = len(dictionaries)
            system_count = sum(1 for d in dictionaries if d['is_system'])
            user_count = total_count - system_count
            
            # 按类型统计
            type_stats = {}
            for type_name in types:
                type_dicts = service.get_dictionaries_by_type(type_name)
                type_stats[type_name] = {
                    'total': len(type_dicts),
                    'system': sum(1 for d in type_dicts if d['is_system']),
                    'user': len(type_dicts) - sum(1 for d in type_dicts if d['is_system'])
                }
            
            # 层级统计
            tree = self.build_tree_structure(dictionaries) if dict_type else []
            max_depth = 0
            
            def calculate_depth(nodes, depth=1):
                nonlocal max_depth
                max_depth = max(max_depth, depth)
                for node in nodes:
                    if node['children']:
                        calculate_depth(node['children'], depth + 1)
            
            if tree:
                calculate_depth(tree)
            
            return {
                'total_count': total_count,
                'system_count': system_count,
                'user_count': user_count,
                'type_count': len(types),
                'max_depth': max_depth,
                'type_statistics': type_stats
            }
            
        except Exception as e:
            logger.error(f"获取统计信息失败: {e}")
            return {}
    
    def export_to_dict(self, dict_type: str = None) -> Dict[str, Any]:
        """
        导出字典数据为字典格式
        
        Args:
            dict_type: 字典类型（可选）
            
        Returns:
            导出数据字典
        """
        from src.app.modules.dictionary.service import DictionaryService
        
        service = DictionaryService()
        
        try:
            export_data = {
                'export_time': datetime.now().isoformat(),
                'version': '1.0',
                'data': {}
            }
            
            if dict_type:
                types = [dict_type]
            else:
                types = service.get_all_types()
            
            for type_name in types:
                dictionaries = service.get_dictionaries_by_type(type_name)
                tree = self.build_tree_structure(dictionaries)
                export_data['data'][type_name] = tree
            
            return export_data
            
        except Exception as e:
            logger.error(f"导出字典数据失败: {e}")
            return {}
    
    def import_from_dict(self, import_data: Dict[str, Any], overwrite: bool = False) -> Dict[str, Any]:
        """
        从字典格式导入数据
        
        Args:
            import_data: 导入数据字典
            overwrite: 是否覆盖现有数据
            
        Returns:
            导入结果
        """
        from src.app.modules.dictionary.service import DictionaryService
        
        service = DictionaryService()
        
        try:
            if 'data' not in import_data:
                return {
                    'success': False,
                    'message': '导入数据格式错误'
                }
            
            success_count = 0
            error_count = 0
            errors = []
            
            for dict_type, tree_nodes in import_data['data'].items():
                # 扁平化树形结构
                dictionaries = self.flatten_tree(tree_nodes)
                
                for dict_data in dictionaries:
                    # 移除不需要的字段
                    clean_data = {k: v for k, v in dict_data.items() 
                                if k in ['dict_type', 'dict_code', 'dict_name', 'parent_code', 
                                       'sort_order', 'is_system', 'description']}
                    
                    # 检查是否已存在
                    existing = service.get_dictionaries_by_type(dict_type, include_system=True)
                    existing_codes = {d['dict_code'] for d in existing}
                    
                    if dict_data['dict_code'] in existing_codes:
                        if overwrite:
                            # 更新现有记录
                            result = service.update_dictionary_by_code(dict_type, dict_data['dict_code'], clean_data)
                            if result['success']:
                                success_count += 1
                            else:
                                error_count += 1
                                errors.append(f"更新失败: {dict_data['dict_code']} - {result['message']}")
                        else:
                            error_count += 1
                            errors.append(f"字典已存在: {dict_data['dict_code']}")
                    else:
                        # 创建新记录
                        result = service.create_dictionary(clean_data)
                        if result['success']:
                            success_count += 1
                        else:
                            error_count += 1
                            errors.append(f"创建失败: {dict_data['dict_code']} - {result['message']}")
            
            return {
                'success': error_count == 0,
                'message': f'导入完成：成功{success_count}条，失败{error_count}条',
                'success_count': success_count,
                'error_count': error_count,
                'errors': errors
            }
            
        except Exception as e:
            logger.error(f"导入字典数据失败: {e}")
            return {
                'success': False,
                'message': f'导入失败: {str(e)}'
            }